/**************************************************
* "uart.c":                                       *
* Implementation file for the Mega32 UART driver. *
*  STK500 setup:                                  *
*  Header "RS232 spare" connected to RXD/TXD:     *
*  RXD = PORTD, bit0                              *
*  TXD = PORTD, bit1                              *
*                                                 *
* Henning Hargaard, 1/11 2011                     *
***************************************************/
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include "uart.h"

// Constants
#define XTAL 8000000 

// Bit addressable I/O
#define RXC  7
#define UDRE 5
#define FE   4
#define DOR  3
#define PE   2

void InitUART( unsigned long BaudRate, unsigned char DataBit, unsigned char Paritet )
{
unsigned char ParityMask = 0;
unsigned int TempUBRR;

  // Only initializations, if parameters is within limits
  if ( (DataBit >= 5) && (DataBit <= 8) && (Paritet <= 2) )
  {	
    // "Normal" clock, no multiprocesser mode (default)
    UCSRA=0b00100000;
    // No interrupts enabled
    // Receiver enabled
    // Transmitter enabled
    // No 9 bit operation
    UCSRB=0b00011000;	
    // Setup the parity and number of Data Bits
    if ( Paritet == 1 )
      ParityMask = 0b00100000;
    else if ( Paritet == 2 )		
      ParityMask = 0b00110000;
    // Asynchronous operation, 1 stop bit
    // Bit7 always has to be 1
    UCSRC = 0b10000000 | ParityMask | ((DataBit-5)<<1) ;
    // Set Baud Rate according to the parameters XTALFrekvens and BaudRate :
    // Select Baud Rate (first store "UBRRH--UBRRL" in local 16-bit variable,
    //                   then write the two 8-bit registers seperately):
    TempUBRR = XTAL/(16*BaudRate) - 1;
    // ( Trick : Adding (BaudRate/2) before division results in correct rounding )
    // ( If you want correkt rounding, substitude the statement above with :
    // ( TempUBRR = (XTALFrekvens/16+(BaudRate/2))/BaudRate - 1; )
    // ( This can be omitted and still working! )
    // Baud Rate Register only has 12 valid bits.
    TempUBRR &= 0x0FFF;
    UBRRH = TempUBRR >> 8;
    UBRRL = TempUBRR & 0x00FF;
  }	
}

/*************************************************************************
CharReady() :
  Returns 0, if the UART has NOT received a new character.
  Returns value <> 0, if the UART HAS received a new character.
*************************************************************************/
unsigned char CharReady()
{
   return UCSRA & (1<<7);
}

/*************************************************************************
RecError() :
Controls the received characters for errors.
Returns :
	0 : No errors in received character, or if no character is received.
	1 : Frame error.
	2 : Overrun Error.
	3 : Parity Error.
*************************************************************************/
unsigned char RecError()
{
   if (FE)
   	return 1;
   if (DOR)
   	return 2;
   if (PE)
   	return 3;
   return 0;
}   

/*************************************************************************
ReadChar() :
Awaits new character received.
Then this character is returned.
*************************************************************************/
char ReadChar()
{
  // Wait for new character received
  while ((UCSRA & (1<<7)) == 0)
  {}                        
  // Then return it
  return UDR;
}

/*************************************************************************
SendChar() :
Awaits transmitter-register ready.
Then it send the character.
Parameter :
	Tegn : Character for sending. 
*************************************************************************/
void SendChar(char ch)
{
  // Wait for transmitter register empty (ready for new character)
  while ( (UCSRA & (1<<5)) == 0 )
  {}
  // Then send the character
  UDR = ch;
}


/*************************************************************************
SendStringSRAM() :
Sends 0-terminated string, stored in SRAM memory.
Parameter :
         *Streng : Pointer to the SRAM-string.
*************************************************************************/
void SendString(char* String)
{
  // Repeat untill zero-termination
  while (*String != 0)
  {
    // Send the character pointed to by "String"
    SendChar(*String);
    // Advance the pointer one step
    String++;
  }
}
/*
char* ReadString()
{
	char* text = malloc(sizeof(char)*16);
	char text[16];
	uint8_t j = 0;
	
	char c;
	do 
	{
		c = ReadChar();
		strcat(text,c);
	} 
	while (c != '\n');
	
	do 
	{
		text[j] = ReadChar();
		j++;
	} 
	while (text[j-1] != '\n');
	
	text[j-1] = 0;
	
	return (text);	
}
*/

char* ReadString(char* text)
{
	char str[30] = {'\0'};    
	uint8_t i = 0;
	
	str[i] = ReadChar();
	while ((str[i] != 58)&(i < 30)) // 58 = ':'
	{
		i++;
		str[i] = ReadChar();
	}	
	str[i] = 0;
    strcat(text,str);   
    return text ;
}